package com.leadingsoft.pwxk.service.impl;

import java.text.DecimalFormat;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;

import org.apache.commons.collections4.map.LinkedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.leadingsoft.common.exception.DataValidateException;
import com.leadingsoft.pwxk.dto.SearchDto;
import com.leadingsoft.pwxk.model.QBaseInfo;
import com.leadingsoft.pwxk.model.QDrainInfoAirOrgCountOne;
import com.leadingsoft.pwxk.model.QDrainInfoAirOrgCountThr;
import com.leadingsoft.pwxk.model.QDrainInfoAirOrgCountTwo;
import com.leadingsoft.pwxk.model.QDrainInfoWaterApplyCountTwo;
import com.leadingsoft.pwxk.model.QDrainInfoWaterApplyOne;
import com.leadingsoft.pwxk.model.QDrainInfoWaterApplyThr;
import com.leadingsoft.pwxk.model.QDrainInfoWaterApplyTwo;
import com.leadingsoft.pwxk.model.QLatestData;
import com.leadingsoft.pwxk.model.QLicenseInfo;
import com.leadingsoft.pwxk.model.QPwBaseInfo;
import com.leadingsoft.pwxk.service.DIStatisticalService;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQuery;

@Service
public class DIStatisticalServiceImpl implements DIStatisticalService {

	@Autowired
	EntityManager em;

	QDrainInfoAirOrgCountOne qDrainInfoAirOrgCountOne = QDrainInfoAirOrgCountOne.drainInfoAirOrgCountOne;

	QLatestData qLatestData = QLatestData.latestData;

	QBaseInfo qBaseInfo = QBaseInfo.baseInfo;

	QPwBaseInfo qPwBaseInfo = QPwBaseInfo.pwBaseInfo;

	QLicenseInfo qLicenseInfo = QLicenseInfo.licenseInfo;

	QDrainInfoAirOrgCountTwo qDrainInfoAirOrgCountTwo = QDrainInfoAirOrgCountTwo.drainInfoAirOrgCountTwo;

	QDrainInfoAirOrgCountThr qDrainInfoAirOrgCountThr = QDrainInfoAirOrgCountThr.drainInfoAirOrgCountThr;

	QDrainInfoWaterApplyOne qDrainInfoWaterApplyOne = QDrainInfoWaterApplyOne.drainInfoWaterApplyOne;

	QDrainInfoWaterApplyTwo qDrainInfoWaterApplyTwo = QDrainInfoWaterApplyTwo.drainInfoWaterApplyTwo;

	QDrainInfoWaterApplyThr qDrainInfoWaterApplyThr = QDrainInfoWaterApplyThr.drainInfoWaterApplyThr;

	QDrainInfoWaterApplyCountTwo qDrainInfoWaterApplyCountTwo = QDrainInfoWaterApplyCountTwo.drainInfoWaterApplyCountTwo;

	@Override
	public Map<String, Double> getStatistical(SearchDto s) {
		if (StringUtils.isBlank(s.getYear())) {
			throw new DataValidateException("年份不能为空");
		}
		if (null == s.getDrainType()) {
			throw new DataValidateException("排放口类型不能为空");
		}
		switch (s.getDrainType()) {
		case AIR_MAIN:
			return get(s,
					new StringPath[] { qDrainInfoAirOrgCountOne.sqoneyear, qDrainInfoAirOrgCountOne.sqtwoyear,
							qDrainInfoAirOrgCountOne.sqthreeyear, qDrainInfoAirOrgCountOne.sqfouryear,
							qDrainInfoAirOrgCountOne.sqfiveyear, qDrainInfoAirOrgCountOne.airwrwname,
							qLicenseInfo.fztime, qDrainInfoAirOrgCountOne.dataid },
					qDrainInfoAirOrgCountOne);
		case AIR_GENERAL:
			return get(s,
					new StringPath[] { qDrainInfoAirOrgCountTwo.sqoneyear, qDrainInfoAirOrgCountTwo.sqtwoyear,
							qDrainInfoAirOrgCountTwo.sqthreeyear, qDrainInfoAirOrgCountTwo.sqfouryear,
							qDrainInfoAirOrgCountTwo.sqfiveyear, qDrainInfoAirOrgCountTwo.airwrwname,
							qLicenseInfo.fztime, qDrainInfoAirOrgCountTwo.dataid },
					qDrainInfoAirOrgCountTwo);
		case AIR_ALL:
			return get(s,
					new StringPath[] { qDrainInfoAirOrgCountThr.sqoneyear, qDrainInfoAirOrgCountThr.sqtwoyear,
							qDrainInfoAirOrgCountThr.sqthreeyear, qDrainInfoAirOrgCountThr.sqfouryear,
							qDrainInfoAirOrgCountThr.sqfiveyear, qDrainInfoAirOrgCountThr.airwrwname,
							qLicenseInfo.fztime, qDrainInfoAirOrgCountThr.dataid },
					qDrainInfoAirOrgCountThr);
		case WATER_MAIN:
			return get(s,
					new StringPath[] { qDrainInfoWaterApplyOne.sqoneyear, qDrainInfoWaterApplyOne.sqtwoyear,
							qDrainInfoWaterApplyOne.sqthreeyear, qDrainInfoWaterApplyOne.sqfouryear,
							qDrainInfoWaterApplyOne.sqfiveyear, qDrainInfoWaterApplyOne.wrwname, qLicenseInfo.fztime,
							qDrainInfoWaterApplyOne.dataid },
					qDrainInfoWaterApplyOne);
		case WATER_GENERAL:
			return get(s,
					new StringPath[] { qDrainInfoWaterApplyTwo.sqoneyear, qDrainInfoWaterApplyTwo.sqtwoyear,
							qDrainInfoWaterApplyTwo.sqthreeyear, qDrainInfoWaterApplyTwo.sqfouryear,
							qDrainInfoWaterApplyTwo.sqfiveyear, qDrainInfoWaterApplyTwo.wrwname, qLicenseInfo.fztime,
							qDrainInfoWaterApplyTwo.dataid },
					qDrainInfoWaterApplyTwo);
		case WATER_FAC:
			return get(s,
					new StringPath[] { qDrainInfoWaterApplyThr.sqoneyear, qDrainInfoWaterApplyThr.sqtwoyear,
							qDrainInfoWaterApplyThr.sqthreeyear, qDrainInfoWaterApplyThr.sqfouryear,
							qDrainInfoWaterApplyThr.sqfiveyear, qDrainInfoWaterApplyThr.wrwname, qLicenseInfo.fztime,
							qDrainInfoWaterApplyThr.dataid },
					qDrainInfoWaterApplyThr);
		case WATER_ALL:
			return get(s,
					new StringPath[] { qDrainInfoWaterApplyCountTwo.sqoneyear, qDrainInfoWaterApplyCountTwo.sqtwoyear,
							qDrainInfoWaterApplyCountTwo.sqthreeyear, qDrainInfoWaterApplyCountTwo.sqfouryear,
							qDrainInfoWaterApplyCountTwo.sqfiveyear, qDrainInfoWaterApplyCountTwo.waterwrwname,
							qLicenseInfo.fztime, qDrainInfoWaterApplyCountTwo.dataid },
					qDrainInfoWaterApplyCountTwo);
		default:
			break;
		}
		throw new DataValidateException("排放口类型不正确");
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map<String, Double> get(SearchDto s, StringPath[] e, EntityPathBase t) {
		JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
		query.select(e[0], e[1], e[2], e[3], e[4], e[5], qLicenseInfo.fztime);
		if (StringUtils.isNotBlank(s.getCodeRegion())) {
			query.from(qLatestData).leftJoin(t).on(qLatestData.dataid.eq(e[7])).leftJoin(qPwBaseInfo)
					.on(qLatestData.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
					.on(qPwBaseInfo.enterid.eq(qBaseInfo.enterid)).leftJoin(qLicenseInfo)
					.on(qLatestData.dataid.eq(qLicenseInfo.dataid));
			query.where(qBaseInfo.code_region.eq(s.getCodeRegion()));

		} else {
			query.from(qLatestData).leftJoin(t).on(qLatestData.dataid.eq(e[7])).leftJoin(qLicenseInfo)
					.on(qLatestData.dataid.eq(qLicenseInfo.dataid));
		}
		return dealData(s, query);
	}

	private Map<String, Double> dealData(SearchDto s, JPAQuery<Tuple> query) {
		List<Tuple> fetch = query.fetch();
		Set<String> nameSet = new LinkedHashSet<String>();
		;
		fetch.forEach(t -> {
			String key = t.get(5, String.class);
			if (StringUtils.isNotBlank(key)) {
				nameSet.add(key);
			}
		});
		Map<String, Double> map = new LinkedMap<String, Double>();
		Integer filterYear = Integer.parseInt(s.getYear());
		DecimalFormat decimalFormat = new DecimalFormat();
		decimalFormat.applyPattern("0.000000");
		for (String name : nameSet) {
			Double total = 0.0;
			for (Tuple t : fetch) {
				if (name.equals(t.get(5, String.class))) {
					Integer fzYear = Integer.parseInt(t.get(6, String.class).substring(0, 4));
					Integer fzMonth = Integer.parseInt(t.get(6, String.class).substring(5, 7));
					Integer fzDay = Integer.parseInt(t.get(6, String.class).substring(8, 10));
					if (fzDay > 15) {
						if (fzMonth < 12) {
							fzMonth++;
						}
					}
					double oneyear = 0.0;
					double twoyear = 0.0;
					double threeyear = 0.0;
					double fouryear = 0.0;
					double fiveyear = 0.0;
					if (null != t.get(0, String.class) && !t.get(0, String.class).equals("/")
							&& !t.get(0, String.class).equals("")) {
						oneyear = Double.valueOf(t.get(0, String.class));
					}
					if (null != t.get(1, String.class) && !t.get(1, String.class).equals("/")
							&& !t.get(1, String.class).equals("")) {
						twoyear = Double.valueOf(t.get(1, String.class));
					}
					if (null != t.get(2, String.class) && !t.get(2, String.class).equals("/")
							&& !t.get(2, String.class).equals("")) {
						threeyear = Double.valueOf(t.get(2, String.class));
					}
					if (null != t.get(3, String.class) && !t.get(3, String.class).equals("/")
							&& !t.get(3, String.class).equals("")) {
						fouryear = Double.valueOf(t.get(3, String.class));
					}
					if (null != t.get(4, String.class) && !t.get(4, String.class).equals("/")
							&& !t.get(4, String.class).equals("")) {
						fiveyear = Double.valueOf(t.get(4, String.class));
					}
					switch (filterYear - fzYear) {
					case 0:
						total += oneyear * (12 - fzMonth) / 12;
						break;
					case 1:
						total += twoyear * (12 - fzMonth) / 12 + oneyear * fzMonth / 12;
						break;
					case 2:
						total += threeyear * (12 - fzMonth) / 12 + twoyear * fzMonth / 12;
						break;
					case 3:
						total += fouryear * (12 - fzMonth) / 12 + threeyear * fzMonth / 12;
						break;
					case 4:
						total += fiveyear * (12 - fzMonth) / 12 + fouryear * fzMonth / 12;
						break;
					default:
						break;
					}
				}
			}
			map.put(name, Double.valueOf(decimalFormat.format(total)));
		}
		return map;
	}

}
